package com.chenfan.mcn.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.enums.*;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.common.extension.lock.DistributedLockTemplate;
import com.chenfan.mcn.model.vo.*;
import com.chenfan.mcn.model.dto.StarRebateContractSaveDTO;
import com.chenfan.mcn.model.dto.StarRebateContractSearchDTO;
import com.chenfan.mcn.model.dto.RelatedExcutionOrderInputDTO;
import com.chenfan.mcn.service.StarRebateContractService;
import com.chenfan.mcn.service.YearFrameContractService;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.utils.CommonUtil;
import com.chenfan.mcn.extension.excel.ExcelUtils;
import com.chenfan.privilege.common.config.SearchAuthority;
import com.chenfan.privilege.common.config.UrlAuth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 红人返点合同
 * @author wulg
 * @since 2021-11-16
 */
@Slf4j
@RestController
@RequestMapping("/starRebateContract")
public class StarRebateContractController {

    @Autowired
    private StarRebateContractService starRebateContractService;

    @Autowired
    private YearFrameContractService yearFrameContractService;

    /**
     * 新增
     * @param saveDTO
     * @return
     */
    @PostMapping("/add")
    @UrlAuth({"redsContract_add"})
    public Res<Long> add(@RequestBody StarRebateContractSaveDTO saveDTO) {
        return Res.ok(starRebateContractService.insertContract(saveDTO));
    }

    /**
     * 修改
     * @param saveDTO
     * @return
     */
    @PostMapping("/modify")
    public Res<Long> update(@RequestBody StarRebateContractSaveDTO saveDTO) {
        BusinessAssert.notNull(saveDTO.getId(), McnErrorCode.PARAM_ERROR, "合同ID不能为空");
        return Res.ok(DistributedLockTemplate.execute(OperateLockEnum.STAR_REBATE_CONTRACT.generateKey(saveDTO.getId()),
                () -> starRebateContractService.updateContract(saveDTO)));
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @GetMapping("/detail")
    public Res<StarRebateContractDetailVO> detail(@RequestParam Long id) {
        BusinessAssert.notNull(id, McnErrorCode.PARAM_ERROR, "合同ID不能为空");
        return Res.ok(starRebateContractService.getContractDetail(id));
    }

    /**
     * 列表查询
     * @param searchDTO
     * @return
     */
    @PostMapping("/page")
    @UrlAuth({"redsContract_search"})
    public Res<Page<StarRebateContractListVO>> page(@SearchAuthority(filterCustomer = false)  StarRebateContractSearchDTO searchDTO) {
        return Res.ok(starRebateContractService.getContractPage(searchDTO));
    }

    /**
     * 列表导出
     * @param searchDTO
     * @param response
     */
    @PostMapping("/export")
    @UrlAuth({"redsContract_export"})
    public void exportExcel(@SearchAuthority(filterCustomer = false)  StarRebateContractSearchDTO searchDTO, HttpServletResponse response) {
        try {
            List<StarRebateContractExportVO> exportPage = CommonUtil.defaultList(starRebateContractService.getExportData(searchDTO));
            ExcelUtils.exportExcel(exportPage, "红人返点合同", StarRebateContractExportVO.class, "红人返点合同.xlsx", response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 合同详情-导出执行单
     * @param id 合同ID
     * @param response
     */
    @GetMapping("/exportExcutionOrder")
    public void exportExcutionOrder(@RequestParam Long id, HttpServletResponse response) {
        try {
            BusinessAssert.notNull(id, McnErrorCode.PARAM_ERROR, "合同ID不能为空");
            List<StarRebateExcutionOrderExportVO> exportPage = CommonUtil.defaultList(starRebateContractService.getExportExcutionOrders(id));
            ExcelUtils.exportExcel(exportPage, "红人返点合同关联的执行单明细", StarRebateExcutionOrderExportVO.class, "红人返点合同关联的执行单明细.xlsx", response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 导入执行单
     *
     * @param multipartFile
     */
    @PostMapping("/excel/importExcutionOrder")
    public Res<List<StarRebateExcutionOrderVO>> importExcutionOrder(@RequestParam MultipartFile multipartFile) {
        List<RelatedExcutionOrderInputDTO> inputList = null;
        try {
            inputList = ExcelUtils.importExcel(multipartFile, RelatedExcutionOrderInputDTO.class);
        } catch (Exception e) {
            throw new BusinessException(McnErrorCode.IMPORT_EXCEL_FAILED);
        }
        return Res.ok(starRebateContractService.importExcel(inputList));
    }

    /**
     * 下载失败原因
     * @param response
     * @param fileId 文件ID
     */
    @Deprecated
    @GetMapping("/excel/download")
    public void excelDownload(HttpServletResponse response, String fileId) {
        log.info("收到红人返点合同Excel下载失败文件请求，fileId={}", fileId);
        starRebateContractService.excelDownload(response, fileId);
    }

    /**
     * 修改单据状态
     *
     * @param id {@link Long} 合同ID
     * @param status   {@link Integer} 状态
     * @return {@link Boolean}
     */
    @GetMapping(value = "/change/approvalStatus")
    @UrlAuth({"redsContract_revocation","redsContract_cancellation","redsContract_submit"})
    public Res<Boolean> changeStatus(@RequestParam Long id, @RequestParam Integer status) {
        BusinessAssert.notNull(id,McnErrorCode.PARAM_ERROR, "合同ID不能为空");
        BusinessAssert.notNull(status,McnErrorCode.PARAM_ERROR, "单据状态不能为空");
        BusinessAssert.notNull(StarRebateStatusEnum.anyMatch(status, StarRebateStatusEnum.APPROVAL, StarRebateStatusEnum.CANCEL, StarRebateStatusEnum.INVALID),
                McnErrorCode.PARAM_ERROR, "非法操作！");
        return Res.ok(DistributedLockTemplate.execute(OperateLockEnum.STAR_REBATE_CONTRACT.generateKey(id),
                () -> starRebateContractService.changeStatus(id, status)));
    }

    /**
     * 红人返点合同-选择年框合同
     *
     * @return 年框合同
     */
    @GetMapping("/getYearFrameContract")
    public Res<List<StarRebateContractYearFrameVO>> getYearFrameContract(@RequestParam(defaultValue = "-1") Long starId) {
        return Res.ok(yearFrameContractService.getYearFrameContractForStarRebate(starId));
    }
}
